package com.googlecode.flair.editors
{
	import com.googlecode.flair.IFlairComponent;
	
	import flash.events.Event;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	
	import mx.containers.FormItem;
	import mx.core.Container;
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
	import mx.styles.CSSStyleDeclaration;
	import mx.utils.ArrayUtil;
	
	[Event(name="valueChanged", type="mx.events.FlexEvent")]
	[Bindable]
	public class BaseEditor extends FormItem implements IFlairEditor
	{
		
		public static var componentDefinitions : XML = new XML();
		public static var componentStyles : XML = new XML();
		private static var componentStyleNames : Dictionary = new Dictionary();
		
		private var _target : Object;
		private var _component : IFlairComponent;
		public var property : String;
		public var properties : Array;
		
		public function BaseEditor()
		{
			super();
		}
		
		
		public final function get target() : Object
		{
			return _target;
		}
		
		public final function set target(newTarget : Object) : void
		{
			this._target = newTarget;
			if (newTarget is UIComponent) 
			{
				UIComponent(newTarget).addEventListener(FlexEvent.VALUE_COMMIT, commitValue);
			}
			dispatchEvent(new Event("valueChanged"));
		}
		
		public final function set component(component : IFlairComponent) : void
		{
			this.target = component.component;
			this._component = component;
			
			if (component.editedProperties[property]) {
				putValue(component.editedProperties[property]);
			} else if (component.editedStyles[property]) {
				putValue(component.editedStyles[property]);
			} else {
				putValue(null);
			}
			dispatchEvent(new Event("valueChanged"));
			checkVisibility();
			
		}
		
		
		private function checkVisibility () : void
		{
			if (!this._component) {
				show(false);
				return;
			}
			if (this.property=="componentId" || Object(this._component.component).hasOwnProperty(this.property)) {
				show();
				return;
			}
			var className : String = getQualifiedClassName(this._component.component);
			var styleNames : Array = componentStyleNames[className] as Array;
			if (!styleNames) {
				var componentXml : XML = componentDefinitions.component.(@name==className)[0];
				var inheritedStyles : String = componentXml.styles.inherited.text().toString();
				styleNames = inheritedStyles.split(" ");
				var specificStyles : String = componentXml.styles.specific.text().toString();
				styleNames = styleNames.concat(specificStyles.split(" "));
				componentStyleNames[className] = styleNames;
			}
			
			if (styleNames.indexOf(property) > -1) {
				show();
				return;
			}
			if (properties && styleNames.indexOf(properties[0]) > -1) {
				show();
				return;
			}
			show(false);
		}
		
		private function show(vizible : Boolean = true) : void {
			if(visible != vizible) {
				this.includeInLayout = vizible;
				this.visible = vizible;
				Container(this.parent).validateNow();
			}
		}
		
		public final function get component() : IFlairComponent
		{
			return this._component;
		}
		
		protected function commitValue(event: Event) : void 
		{
			dispatchEvent(new Event("valueChanged"));
		}
		
		protected function putValue(value : Object) : Object
		{
			if (value != null) {
				this._component.putValue(property, value);
			}
			return value;
		}
		
		
		protected function putValues(values : Array) : void
		{
			if (properties && properties.length == values.length) {
				this._component.putValues(properties, values);
			} else {
				this._component.putValue(property, values);
			}
		}
		
		[Bindable(event="valueChanged")]
		protected function getValue() : Object
		{
			return this._component.getValue(property);
		}
		
		[Bindable(event="valueChanged")]
		protected function getArrayValue(index : Number) : Object
		{
			if (properties) {
				return this._component.getArrayValue(properties, index);
			} else {
				return this._component.getArrayValue(property, index);
			}
		}
		
	}
}